package scfg.utils.trainging_results;

import desposito6.math.*;

import java.util.*;
import scfg.Grammar;

/**
 * The Class StatsCollector.
 */
public class StatsCollector {

	/** The grams. */
	private List<Grammar> grams;

	/** The contents. */
	private String contents;

	/**
	 * Gets the grammars list.
	 * 
	 * @return the grammars list
	 */
	public List<Grammar> getGrammarsList() {
		return grams;
	}

	/**
	 * Instantiates a new stats collector.
	 */
	public StatsCollector() {
		new StatsRun();
		grams = new ArrayList<Grammar>();
	}

	/**
	 * Adds the.
	 * 
	 * @param g
	 *            the g
	 */
	public void add(Grammar g) {
		grams.add(g);
	}

	/**
	 * Update.
	 * 
	 * @return the string
	 */
	public String update() {
		contents = StatsCollector.testCollection(this);
		return contents;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		return contents == null ? "" : contents;
	}

	/**
	 * Process2 d.
	 * 
	 * @param grammar_params
	 *            the grammar_params
	 * @param sr_params
	 *            the sr_params
	 */
	public static void process2D(iDouble[] grammar_params,
			StatsDouble[] sr_params) {
		if (grammar_params != null)
			for (int i = 0; i < grammar_params.length; i++)
				sr_params[i].add(grammar_params[i]);
	}

	/**
	 * Process3 d.
	 * 
	 * @param grammar_params
	 *            the grammar_params
	 * @param sr_params
	 *            the sr_params
	 */
	public static void process3D(iDouble[][] grammar_params,
			StatsDouble[][] sr_params) {
		if (grammar_params != null)
			for (int i = 0; i < grammar_params.length; i++)
				for (int j = 0; j < grammar_params[0].length; j++)
					sr_params[i][j].add(grammar_params[i][j]);
	}

	/**
	 * Test collection.
	 * 
	 * @param sc
	 *            the sc
	 * @return the string
	 */
	public static String testCollection(StatsCollector sc) {
		List<Grammar> grams = sc.getGrammarsList();
		StatsRun sr = new StatsRun();
		for (Grammar g : grams) {
			processGrammar(g, sr);
		}
		return sr.toString();
	}

	/**
	 * Process grammar.
	 * 
	 * @param g
	 *            the g
	 * @param sr
	 *            the sr
	 */
	public static void processGrammar(Grammar g, StatsRun sr) {
		if (g.get_kh_params()[0].isZero())
			System.out.println("problem");
		process2D(g.get_kh_params(), sr.kh_params);
		process2D(g.get_kh_perc(), sr.kh_perc);
		process2D(g.get_nucleotide_dist(), sr.nucleotideDist);
		process2D(g.get_pfold_params_u(), sr.pfold_params_u);
		process3D(g.get_pfold_params_p(), sr.pfold_params_p);
		process3D(g.get_pfold_ratio(), sr.pfold_ratio);
	}

	/**
	 * The Class StatsRun.
	 */
	private static class StatsRun {

		/** The kh_perc. */
		public StatsDouble[] kh_params, kh_perc;

		/** The pfold_params_u. */
		public StatsDouble[] nucleotideDist, pfold_params_u;

		/** The pfold_ratio. */
		public StatsDouble[][] pfold_params_p, pfold_ratio;

		/**
		 * Instantiates a new stats run.
		 */
		public StatsRun() {
			kh_params = new StatsDouble[3];
			kh_perc = new StatsDouble[4];
			for (int i = 0; i < 3; i++) {
				kh_params[i] = new StatsDouble();
				kh_perc[i] = new StatsDouble();
			}
			pfold_params_u = new StatsDouble[4];
			nucleotideDist = new StatsDouble[4];
			pfold_params_p = new StatsDouble[4][4];
			pfold_ratio = new StatsDouble[4][4];
			for (int i = 0; i < 4; i++) {
				pfold_params_u[i] = new StatsDouble();
				nucleotideDist[i] = new StatsDouble();
				for (int j = 0; j < 4; j++) {
					pfold_params_p[i][j] = new StatsDouble();
					pfold_ratio[i][j] = new StatsDouble();
				}
			}
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see java.lang.Object#toString()
		 */
		@Override
		public String toString() {
			String[] kh_headers = new String[] { "S->L  ", "L->s  ", "F->LS " };
			String[] pfold_headers_u = new String[] { "s->A ", "s->C ",
					"s->G ", "s->U " };
			String[] pfold_headers_p = new String[] { "A  ", "C  ", "G  ",
					"U  " };
			StringBuilder sb = new StringBuilder("\n");
			sb.append("------------------------\n");
			sb.append("STATS COLLECTOR RESULTS:\n");
			sb.append("------------------------\n\n");

			sb.append("\n\nKnudsen-Hein Grammar Production Probabilities:\n");
			sb.append("----------------------------------------------\n");
			for (int i = 0; i < kh_headers.length; i++)
				sb.append(kh_headers[i]).append(kh_params[i]).append("\n");

			sb.append("\n\nKnudsen-Hein Grammar State Percentages:\n");
			sb.append("-------------------------------------------\n");
			for (int i = 0; i < kh_headers.length; i++)
				sb.append(kh_headers[i]).append(kh_perc[i]).append("\n");

			if (nucleotideDist != null) {
				sb.append("\n\n");
				sb.append("Pfold Grammar Nucleotide Distribution:\n");
				sb.append("--------------------------------------\n");
				for (int i = 0; i < nucleotideDist.length; i++)
					sb.append(pfold_headers_u[i]).append(nucleotideDist[i])
							.append("\n");
			}

			if (pfold_headers_u != null) {
				sb.append("\n\n");
				sb
						.append("Pfold Grammar Unmatched Production Probabilities:\n");
				sb
						.append("-------------------------------------------------\n");
				for (int i = 0; i < pfold_params_u.length; i++)
					sb.append(pfold_headers_u[i]).append(pfold_params_u[i])
							.append("\n");
			}

			if (pfold_headers_p != null) {
				sb.append("\n\n");
				sb
						.append("Pfold Grammar Base Pair Production Probabilities:\n");
				sb
						.append("-------------------------------------------------\n");
				String[][] arr = new String[5][5];
				int max = 0;
				for (int i = 0; i < 4; i++) {
					arr[i + 1][0] = pfold_headers_p[i];
					arr[0][i + 1] = pfold_headers_p[i];
					for (int j = 0; j < 4; j++) {
						arr[i + 1][j + 1] = pfold_params_p[i][j].toString();
						max = max >= arr[i + 1][j + 1].length() ? max
								: arr[i + 1][j + 1].length();
					}
				}
				arr[0][0] = "   ";
				for (int i = 1; i < 5; i++) {
					for (int j = 0; j < 5; j++) {
						sb.append(arr[j][0]).append(arr[j][i]).append("\n");
					}
					sb.append("\n");
				}
			}

			if (pfold_headers_p != null) {
				sb.append("\n\n");
				sb.append("Pfold Grammar Base Pair Ratio to G-U:\n");
				sb.append("-------------------------------------\n");
				String[][] arr = new String[5][5];
				int max = 0;
				for (int i = 0; i < 4; i++) {
					arr[i + 1][0] = pfold_headers_p[i];
					arr[0][i + 1] = pfold_headers_p[i];
					for (int j = 0; j < 4; j++) {
						arr[i + 1][j + 1] = pfold_ratio[i][j].toString();
						max = max >= arr[i + 1][j + 1].length() ? max
								: arr[i + 1][j + 1].length();
					}
				}
				arr[0][0] = "   ";
				for (int i = 1; i < 5; i++) {
					for (int j = 0; j < 5; j++) {
						sb.append(arr[j][0]).append(arr[j][i]).append("\n");
					}
					sb.append("\n");
				}
			}
			return sb.toString();
		}
	}
}
